package com.sinovatech.ologger.core.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Generics的util类.
 * 
 */
@SuppressWarnings("unchecked")
public class GenericsUtils {
	private static final Log log = LogFactory.getLog(GenericsUtils.class);

	private GenericsUtils() {
	}

	public static String getDateStrBySqlDate(Date date) {
		return new java.text.SimpleDateFormat("yyyy-MM-dd").format(date);
	}

	public static String getDateStrBySqlDate(java.util.Date date) {
		return new java.text.SimpleDateFormat("yyyy-MM-dd").format(date);
	}

	public static String getFullTimeByUtilDate(java.util.Date date) {
		return new java.text.SimpleDateFormat("yyyy-MM-dd#HH:mm").format(date);
	}
	
	public static String getMonthAndDate(java.util.Date date){
		return new java.text.SimpleDateFormat("MM-dd").format(date);
	}

	public static String getCompareDate(java.util.Date date) {
		return new java.text.SimpleDateFormat("yyyyMMdd").format(date);
	}

	public static String getCompareDate(java.sql.Date date) {
		return new java.text.SimpleDateFormat("yyyyMMdd").format(date);
	}

	public static String tuneDateFormat(String orig) {// 将2008-1-1这样的形式转换为2008-01-01的形式方便比较
		try {
			String[] ymd = orig.split("-");
			int y = Integer.parseInt(ymd[0]);
			int m = Integer.parseInt(ymd[1]) - 1;
			int d = Integer.parseInt(ymd[2]);
			Calendar c = Calendar.getInstance();
			c.set(y, m, d);
			return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
		} catch (Exception ex) {
			return null;
		}
	}

	public static Date getSqlDateByYMD(String ymd) {
		String[] ymdArr = ymd.split("-");
		int y = Integer.parseInt(ymdArr[0]);
		int m = Integer.parseInt(ymdArr[1]) - 1;
		int d = Integer.parseInt(ymdArr[2]);

		Calendar c = Calendar.getInstance();
		c.set(y, m, d);
		return new java.sql.Date(c.getTimeInMillis());
	}

	// 该方法返回某天的星期
	public static int getWeekByYMD(String ymd) {
		String[] ymdFromArr = ymd.split("-");
		int yf = Integer.parseInt(ymdFromArr[0]);
		int mf = Integer.parseInt(ymdFromArr[1]) - 1;
		int df = Integer.parseInt(ymdFromArr[2]);
		Calendar cf = Calendar.getInstance();
		cf.set(Calendar.YEAR, yf);
		cf.set(Calendar.MONTH, mf);
		cf.set(Calendar.DATE, df);
		return cf.get(Calendar.DAY_OF_WEEK);
	}

	//该方法返回某天的某个日期
	public static String getDateBySomeDate(String ymd, int dayNum) {
		String[] ymdFromArr = ymd.split("-");
		int yf = Integer.parseInt(ymdFromArr[0]);
		int mf = Integer.parseInt(ymdFromArr[1]) - 1;
		int df = Integer.parseInt(ymdFromArr[2]);
		Calendar cf = Calendar.getInstance();
		cf.set(Calendar.YEAR, yf);
		cf.set(Calendar.MONTH, mf);
		cf.set(Calendar.DATE, df);
		cf.add(Calendar.DATE, dayNum);
		return GenericsUtils.getDateStrBySqlDate(cf.getTime());
	}

	@SuppressWarnings("deprecation")
	public static List<Date> getSqlDatesByYMD(String ymdFrom, String ymdTo) {
		String[] ymdFromArr = ymdFrom.split("-");
		int yf = Integer.parseInt(ymdFromArr[0]);
		int mf = Integer.parseInt(ymdFromArr[1]) - 1;
		int df = Integer.parseInt(ymdFromArr[2]);

		Calendar cf = Calendar.getInstance();
		cf.set(yf, mf, df);
		Date dateFrom = new Date(cf.getTimeInMillis());

		String[] ymdToArr = ymdTo.split("-");
		int yt = Integer.parseInt(ymdToArr[0]);
		int mt = Integer.parseInt(ymdToArr[1]) - 1;
		int dt = Integer.parseInt(ymdToArr[2]);

		Calendar ct = Calendar.getInstance();
		ct.set(yt, mt, dt);
		Date dateTo = new Date(ct.getTimeInMillis());

		Date tmpDate = new Date(dateFrom.getTime());
		List dateList = new ArrayList();
		while (tmpDate.compareTo(dateTo) <= 0) {
			dateList.add(new Date(tmpDate.getTime()));
			tmpDate.setDate(tmpDate.getDate() + 1);
		}
		return dateList;
	}

	/**
	 * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
	 * 
	 * @param clazz
	 *            The class to introspect
	 * @return the first generic declaration, or <code>Object.class</code> if
	 *         cannot be determined
	 */
	public static Class getSuperClassGenricType(Class clazz) {
		return getSuperClassGenricType(clazz, 0);
	}

	/**
	 * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
	 * 
	 * @param clazz
	 *            clazz The class to introspect
	 * @param index
	 *            the Index of the generic ddeclaration,start from 0.
	 * @return the index generic declaration, or <code>Object.class</code> if
	 *         cannot be determined
	 */
	public static Class getSuperClassGenricType(Class clazz, int index) {

		Type genType = clazz.getGenericSuperclass();

		if (!(genType instanceof ParameterizedType)) {
			log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
			return Object.class;
		}

		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

		if (index >= params.length || index < 0) {
			log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
					+ params.length);
			return Object.class;
		}
		if (!(params[index] instanceof Class)) {
			log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
			return Object.class;
		}
		return (Class) params[index];
	}
}
